// 9.6 容器适配器
/**
 * 除了顺序容器外，标准库还定义了三个顺序容器适配器：stack、queue和priority_queue。
 * 适配器（adaptor）是标准库中的一个通用概念。
 * 容器、迭代器和函数都有适配器。本质上，一个适配器是一种机制，能使某种事物的行为看起来像另外一种事物一样。
 */

#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::cin, std::cout, std::endl;

int main()
{
    // 定义一个适配器
    deque<int> deq;
    stack<int> stk(deq);                   // 从deq拷贝元素到stk
    stack<string, vector<string>> str_stk; // 在vector上实现的空栈
    vector<string> svec;
    stack<string, vector<string>> str_stk2(svec); // str_stk2在vector上实现，初始化时保存svec的拷贝
    // 默认情况下，stack和queue是基于deque。priority_queue实在vector之上实现的。
    // 所有适配器都要求容器具有添加和删除元素的能力。因此，适配器不能构造在array之上。
    // 类似的，我们也不能用forward_list来构造适配器，因为所有适配器都要求容器具有添加、删除以及访问尾元素的能力。

    // 所有适配器都要求容器具有添加和删除元素的能力。因此，适配器不能构造在array之上。
    // 类似的，我们也不能用forward_list来构造适配器，因为所有适配器都要求容器具有添加、删除以及访问尾元素的能力。
    // stack只要求push_back、pop_back和back操作，因此可以使用除array和forward_list之外的任何容器类型来构造stack。
    // queue适配器要求back、push_back、front和push_front，因此它可以构造于list或deque之上，但不能基于vector构造。priority_queue除了front、push_back和pop_back操作之外还要求随机访问能力，因此它可以构造于vector或deque之上，但不能基于list构造。

    // 栈适配器
    stack<int> intStack; // 空栈
    for (size_t ix = 0; ix != 10; ++ix)
    {
        intStack.push(ix); // intStack保存0到9十个数
    }
    while (!intStack.empty())
    {
        int value = intStack.top(); // 栈顶值
        // 使用栈顶值value的代码...
        intStack.pop(); // 弹出栈顶元素，继续循环
    }
    

    // 队列适配器
    // queue和priority_queue适配器定义在queue头文件中。表9.19列出了它们所支持的操作。[插图]续表[插图]
    queue<int> intQueue; // 空队列
    for (size_t ix = 0; ix != 10; ++ix)
    {
        intQueue.push(ix); // intQueue保存0到9十个数
    }
    while (!intQueue.empty())
    {
        int value = intQueue.front(); // 返回首元素或尾元素，但不删除此元素
        int value2 = intQueue.back(); // 只适用于queue
        // 使用首元素value的代码...
        intQueue.pop(); // 返回queue的首元素或priority_queue的最高优先级元素，但不删除此元素
    }

    return 0;
}